package net.jxtz.jxtzos.spider.process;


import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import net.jxtz.jxtzos.entity.spider.SpiderLandTransactionV2;
import net.jxtz.jxtzos.entity.spider.SpiderLogServe;
import net.jxtz.jxtzos.service.spider.SpiderLandTransactionV2Service;
import net.jxtz.jxtzos.spider.BaseSpiderProcessor;
import net.jxtz.jxtzos.spider.SpiderDefinition;
import net.jxtz.jxtzos.spider.SpiderFactory;
import net.jxtz.jxtzos.util.StampToDateAndDateToStamp;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author lmh
 */

@Component
@Slf4j
public class SpiderLandTransactionV2Processor implements BaseSpiderProcessor {

    private final AtomicInteger pageNum = new AtomicInteger(1);

    public static final String SPIDER_NAME = "landTransaction";

    private final static int MAX_PAGE = 50;

    private Long spiderLogId = null;

    public SpiderLandTransactionV2Processor() {
        SpiderFactory instance = SpiderFactory.getInstance();
        instance.putSpiderProcess(SPIDER_NAME, this);
        SpiderDefinition spiderDefinition = new SpiderDefinition("江西省土地交易", SPIDER_NAME);
        spiderDefinition.setImgUrl("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimgs.focus.cn%2Fupload%2Fpics%2F39791%2Fb_397903120.jpg&refer=http%3A%2F%2Fimgs.focus.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1635297177&t=17106ce20a26c10363329076eeccf856");
        instance.putSpiderDefinition(SPIDER_NAME, spiderDefinition);
    }

    private Integer lastTime;

    public Integer getLastTime() {
        return lastTime;
    }

//    List<SpiderLandTransactionV2> list = new ArrayList<>();

//    private final AtomicInteger countNum = new AtomicInteger(0);

    @Autowired
    private SpiderLandTransactionV2Service service;

    private Integer count;

    public Integer getCount() {
        return count;
    }

    @SneakyThrows
    private boolean process(Integer page) {
        TimeUnit.SECONDS.sleep(3);
        String url = "http://jxgtjy.jxsggzy.cn/index.jsp?pageNo=" + page;
        String s = httpGet(url);
        if (s == null || "".equals(s)) return false;
        Document document = Jsoup.parse(s);
        List<SpiderLandTransactionV2> list = new ArrayList<>();

        // 拿到所有交易类型
        Map<String, String> map = new HashMap<>();
        Element rdbProgress = document.getElementById("rdbProgress");
        Elements option = rdbProgress.getElementsByTag("option");
        for (Element element : option) {
            String attr = element.attr("value");
            String text = element.text();
            map.put(attr, text);
        }

        // 列表
        Elements suoyougonggaoTd0 = document.getElementsByClass("suoyougonggao_td_0");
        // table
        Elements guapaiTd1 = suoyougonggaoTd0.get(0).getElementsByClass("guapai_td_1");
        for (Element element : guapaiTd1) {
            Elements suoyougonggaoTdRow1 = element.getElementsByClass("suoyougonggao_td_Row1");
            Elements suoyougonggaoWz01 = suoyougonggaoTdRow1.get(0).getElementsByClass("suoyougonggao_wz01");
            // 城市
            String cityArea = suoyougonggaoWz01.get(0).text();
            // 交易来源
            String transactionSource = suoyougonggaoWz01.get(1).text();
            // 交易编号
            String transactionId = suoyougonggaoWz01.get(2).text();
            Elements dk1 = element.getElementsByClass("fPageNowRow").get(0).getElementsByClass("dk_1");
            // 地块table
            for (Element i : dk1) {
                // 拍卖类型
                String transactionType = i.getElementsByTag("td").get(0).text();
                String td = i.getElementsByTag("td").get(1).text();
                // 地块编号
                String number = td.substring(td.lastIndexOf(":") + 1);

                /**
                 *
                 *
                 * 详情页
                 *
                 */
                String onclick = i.getElementsByClass("btn_chujiaxiangqing").get(0).attr("onclick");
                // 提id
                String id = Pattern.compile("[^0-9]").matcher(onclick).replaceAll("");
                // 进入详情页
                CloseableHttpClient httpClient = HttpClients.createDefault();
                HttpGet httpGet = new HttpGet("http://jxgtjy.jxsggzy.cn/monitor/ScheduleL.jsp?lx=L&id=" + id);
                RequestConfig build1 = RequestConfig.custom()
                        .setSocketTimeout(60000)
                        .setConnectTimeout(60000)
                        .setConnectionRequestTimeout(60000)
                        .build();
                httpGet.setConfig(build1);
                TimeUnit.SECONDS.sleep(3);
                CloseableHttpResponse response = httpClient.execute(httpGet);
                String s1 = null;
                if (response.getStatusLine().getStatusCode() == 200){
                    s1 = EntityUtils.toString(response.getEntity());
                }

                // 详情页
                Document doc = Jsoup.parse(s1);

                // 交易状态
                String statCode = map.get(doc.getElementById("statCode").attr("value"));
                SpiderLandTransactionV2 spiderLandTransactionV2 = new SpiderLandTransactionV2();
                spiderLandTransactionV2.setCityArea(cityArea);
                spiderLandTransactionV2.setExchangeNumber(transactionId);
                spiderLandTransactionV2.setType(transactionType);
                spiderLandTransactionV2.setParcelNumber(number);
                spiderLandTransactionV2.setTransactionSource(transactionSource);
                spiderLandTransactionV2.setStatCode(statCode);
                Elements td1 = doc.getElementsByTag("td");
                log.info("当前：" + cityArea + "，地块编号：" + number);
                for (int j = 0; j < td1.size(); j++) {
                    String text = td1.get(j).text().replaceAll(" ","");
                    switch (text){
                        case "地块编号":
                            String pricePage = "http://jxgtjy.jxsggzy.cn/public/resultShow_qrjg.jsp";
                            List<NameValuePair> nameValuePairs = new ArrayList<>();
                            nameValuePairs.add(new BasicNameValuePair("xzqdm", ""));
                            nameValuePairs.add(new BasicNameValuePair("xzqdmMcCon", "所有区域"));
                            nameValuePairs.add(new BasicNameValuePair("res_type_value", "L"));
                            long l = System.currentTimeMillis();
                            int time = (int) (l / 1000);
                            nameValuePairs.add(new BasicNameValuePair("time2", l + ""));
                            nameValuePairs.add(new BasicNameValuePair("time1", "1546272000000")); // 2019-1-1
                            nameValuePairs.add(new BasicNameValuePair("bb_no", ""));
                            nameValuePairs.add(new BasicNameValuePair("f_pno", number));
                            nameValuePairs.add(new BasicNameValuePair("xzqmc", "所有区域"));
                            nameValuePairs.add(new BasicNameValuePair("f_closetime1", "2019-4-1"));
                            nameValuePairs.add(new BasicNameValuePair("f_closetime2", StampToDateAndDateToStamp.stampToDate(time, "yyyy-MM-dd")));
                            nameValuePairs.add(new BasicNameValuePair("xzqmc", "所有区域"));
                            nameValuePairs.add(new BasicNameValuePair("SearchPageNo", "1"));

                            CloseableHttpClient httpClient1 = HttpClients.createDefault();
                            RequestConfig build = RequestConfig.custom()
                                    .setConnectionRequestTimeout(60000)
                                    .setSocketTimeout(60000)
                                    .setConnectTimeout(60000)
                                    .build();// 毫秒
                            HttpPost httpPost = new HttpPost(pricePage);
                            httpPost.setConfig(build);
                            CloseableHttpResponse response1 = null;
                            String s2 = null;
                            try {
                                TimeUnit.SECONDS.sleep(3);
                                httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "utf-8"));
                                response1 = httpClient1.execute(httpPost);
                                if (response1.getStatusLine().getStatusCode() == 200) {
                                    s2 = EntityUtils.toString(response1.getEntity());
                                }
                            } catch (IOException e) {
                                e.printStackTrace();
                            } finally {
                                if (httpClient1 != null) {
                                    try {
                                        httpClient.close();
                                    } catch (IOException e) {
                                        e.printStackTrace();
                                    }
                                }

                                if (response1 != null) {
                                    try {
                                        response.close();
                                    } catch (IOException e) {
                                        e.printStackTrace();
                                    }
                                }
                            }
                            if (s2 != null){
                                Document parse = Jsoup.parse(s2);
                                Elements td2 = parse.getElementsByClass("TD1");
                                for (int k = 0; k < td2.size(); k++) {
                                    switch (k) {
                                        case 4:
                                            // 起始价
                                            String startPrice = td2.get(k).text();
                                            spiderLandTransactionV2.setStartingPrice(startPrice);
                                            break;
                                        case 5:
                                            // 成交价
                                            String endPrice = td2.get(k).text();
                                            spiderLandTransactionV2.setTotalPrice(endPrice);
                                            break;
                                        case 6:
                                            // 竞得人
                                            String winner = td2.get(k).text();
                                            spiderLandTransactionV2.setWinner(winner);
                                            break;
                                        case 7:
                                            // 成交确认时间
                                            String endTime = td2.get(k).text();
                                            spiderLandTransactionV2.setTransactionDate(endTime);
                                            break;
                                        default:
                                            System.out.println("没有符合的对象");
                                    }
                                }
                            }else {
                                log.info("地块编号：" + number + "成交信息为空");
                            }

                            break;
                        case "地块名称":
                            spiderLandTransactionV2.setLandName(td1.get(j + 1).text());
                            break;
                        case "地块位置":
                            spiderLandTransactionV2.setPosition(td1.get(j + 1).text());
                            break;
                        case "出让方式":
                            spiderLandTransactionV2.setTransferMode(td1.get(j + 1).text());
                            break;
                        case "土地用途":
                            spiderLandTransactionV2.setLandUse(td1.get(j + 1).text());
                            break;
                        case "地块面积":
                            String area = td1.get(j + 1).text();
                            if (area.contains("亩")){
                                Pattern compile = Pattern.compile("(\\d+\\.\\d+)|(\\d+)");
                                Matcher matcher = compile.matcher(area);
                                matcher.find();
                                // 单位换算
                                Double end = Double.valueOf(matcher.group()) * 666.67;
                                spiderLandTransactionV2.setPlotArea(end.toString() + "平方米");
                            }else {
                                spiderLandTransactionV2.setPlotArea(area);
                            }
                            break;
                        case "容积率(FAR)":
                            spiderLandTransactionV2.setPlotRatio(td1.get(j + 1).text());
                            break;
                        case "建筑密度（D）":
                            spiderLandTransactionV2.setBuildingDensity(td1.get(j + 1).text());
                            break;
                        case "绿地率(GAR)":
                            spiderLandTransactionV2.setGreenSpaceRate(td1.get(j + 1).text());
                            break;
                        case "保证金截止时间":
                            spiderLandTransactionV2.setBzjEndTime(td1.get(j + 1).text());
                            break;
                        case "拍卖开始时间":
                            spiderLandTransactionV2.setPaimaiStartTime(td1.get(j + 1).text());
                            break;
                        case "挂牌起始时间":
                            spiderLandTransactionV2.setGuapaiStartTime(td1.get(j + 1).text());
                            break;
                        case "挂牌截止时间":
                            spiderLandTransactionV2.setGuapaiEndTime(td1.get(j + 1).text());
                            break;
                        default:

                    }

                }
                if (spiderLogId != null) {
                    spiderLandTransactionV2.setSpiderLogId(spiderLogId);
                }
                list.add(spiderLandTransactionV2);
            }

        }

        service.saveBatch(list);

        return true;
    }

    @SneakyThrows
    private String httpGet(String url) throws IOException {
        TimeUnit.SECONDS.sleep(3);
        String s = null;
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);
        List<NameValuePair> nameValuePairs = new ArrayList<>();
        nameValuePairs.add(new BasicNameValuePair("res_type_value", "L"));
        nameValuePairs.add(new BasicNameValuePair("scope", ""));
        nameValuePairs.add(new BasicNameValuePair("rdbProgressCon", "V"));
        nameValuePairs.add(new BasicNameValuePair("xzqdm", ""));
        nameValuePairs.add(new BasicNameValuePair("xzqdmMcCon", ""));
        nameValuePairs.add(new BasicNameValuePair("onlyUser", ""));
        nameValuePairs.add(new BasicNameValuePair("querys", "nouse"));
        nameValuePairs.add(new BasicNameValuePair("bb_no", ""));
        nameValuePairs.add(new BasicNameValuePair("f_no", ""));
        nameValuePairs.add(new BasicNameValuePair("f_beigintime1", ""));
        nameValuePairs.add(new BasicNameValuePair("f_beigintime2", ""));
        nameValuePairs.add(new BasicNameValuePair("f_closetime1", ""));
        nameValuePairs.add(new BasicNameValuePair("f_closetime2", ""));
        nameValuePairs.add(new BasicNameValuePair("f_bailtime1", ""));
        nameValuePairs.add(new BasicNameValuePair("f_bailtime2", ""));
        nameValuePairs.add(new BasicNameValuePair("f_pos", ""));
        nameValuePairs.add(new BasicNameValuePair("fxzqmc", "请输入行政区名称或拼音首字母"));
        nameValuePairs.add(new BasicNameValuePair("rdbProgress", "V"));
        nameValuePairs.add(new BasicNameValuePair("f_notxt", ""));
        nameValuePairs.add(new BasicNameValuePair("SearchPageNo", "1"));

        httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
        CloseableHttpResponse response = httpClient.execute(httpPost);
        if (response.getStatusLine().getStatusCode() == 200){
            s = EntityUtils.toString(response.getEntity());
        }

        return s;
    }

    @Override
    public void start(SpiderLogServe spiderLogServe, SpiderDefinition spiderDefinition) {
        spiderLogId = spiderLogServe.getId();
        long startTime = System.currentTimeMillis() / 1000;
        int startCount = service.count();
        log.info("开始爬取");

        boolean flag = true;

        int page = 1;
        try {
            while (flag || page <= MAX_PAGE) {
                flag = process(page++);
                TimeUnit.SECONDS.sleep(3);
            }
        }catch (Exception e){
            e.printStackTrace();
        }

        long endTime = System.currentTimeMillis() / 1000;
        long time = endTime - startTime;
        int endCount = service.count();
        count = endCount - startCount;
        lastTime = Long.valueOf(endTime).intValue();
        spiderLogServe.setCount(count);
        log.info("爬取完毕，用时：" + time + "s，更新数量：" + count);
    }
}
